package com.bc.trade.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.bc.common.CommonEnum.OrderStatus;
import com.bc.common.CommonEnum.Resp;
import com.bc.common.PayType;
import com.bc.common.message.AppidPayReq;
import com.bc.common.message.AppidWxgjPayReq;
import com.bc.common.message.BaseResp;
import com.bc.common.message.BlankNoteReq;
import com.bc.common.message.DFReq;
import com.bc.common.message.TransferQrcodeReq;
import com.bc.common.message.WxgjClearingReq;
import com.bc.trade.config.R;
import com.bc.trade.message.BindBankCardReq;
import com.bc.trade.message.BindBankCardVerifyReq;
import com.bc.trade.message.QueryBalanceReq;
import com.bc.trade.message.QueryBalanceResp;
import com.bc.trade.message.QueryCardInfoReq;
import com.bc.trade.message.QueryOrderReq;
import com.bc.trade.message.QuickPayReq;
import com.bc.trade.message.QuickPaySetReq;
import com.bc.trade.message.RefundReq;
import com.bc.trade.message.SendSMSReq;
import com.bc.trade.message.UnionPayReq;
import com.bc.trade.model.Account;
import com.bc.trade.model.Merch;
import com.bc.trade.model.RiskRule;
import com.bc.trade.model.TradeOrder;
import com.bc.trade.model.TradeStrategy;
import com.bc.trade.util.Strings;
import com.bc.trade.vo.MessageFieldCheck;
import com.bc.trade.vo.RiskRuleCheck;
import com.bc.trade.vo.TradeElement;
import com.fs.common.util.FSDate;
import com.fs.common.util.FSLog;
import com.fs.common.util.FSRegex;
import com.jfinal.kit.StrKit;

/**
 * RouteController 分发到这个类，有各自业务的数据校验，风控
 * 
 * @author zhongzhanfeng
 *
 */
public class RouteService {

	private OrderService orderService = new OrderService();
	
	public void visaPay(Map<String, String> reqMap) {
		String processCode = reqMap.get("processCode");
		String bankCode  = reqMap.get("bankCode");
		String merchantNo = reqMap.get("merchantNo");
		if(Strings.isNullOrEmpty(merchantNo)) {
			FSLog.api.info("Visa 数据错误 ------ > " + "merchantNo");
			return;
		}
		if(!"00010000-001".equals(bankCode) || !"190011".equals(processCode)) {
			FSLog.api.info("Visa 数据错误 ------ > " + "bankCode,  processCode");
			return;
		}
		
		orderService.visaPay(reqMap);
		
	}

	public BaseResp query(QueryOrderReq req) throws Exception {
		BaseResp rsp = new BaseResp(req);
		List<MessageFieldCheck> fieldCheck = new ArrayList<MessageFieldCheck>();
		fieldCheck.add(new MessageFieldCheck("merchCode", req.getMerchCode(), true));
		fieldCheck.add(new MessageFieldCheck("merchOrderNo", req.getMerchOrderNo(), true));
		// 非空、必填、固定值、长度
		String checkMsg = MessageFieldCheck.check(fieldCheck);
		if (StrKit.notBlank(checkMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), checkMsg);
		}
		return orderService.query(req);
	}
	
	public BaseResp unionpay(UnionPayReq req) {
		BaseResp rsp = new BaseResp(req);
		if (FSRegex.isPositiveInt(req.getAmount()) == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "金额错误，金额以分为单位，必须是正整数");
		}
		List<MessageFieldCheck> fieldCheck = new ArrayList<MessageFieldCheck>();
		fieldCheck.add(new MessageFieldCheck("merchOrderNo", req.getMerchOrderNo(), true));
		fieldCheck.add(new MessageFieldCheck("amount", req.getAmount(), true));
		fieldCheck.add(new MessageFieldCheck("goodsName", req.getGoodsName(), true));
		fieldCheck.add(new MessageFieldCheck("cardType", req.getCardType(), true));
		fieldCheck.add(new MessageFieldCheck("bankType", req.getBankType(), true));
		fieldCheck.add(new MessageFieldCheck("orderPeriod", req.getOrderPeriod(), true));
		fieldCheck.add(new MessageFieldCheck("callbackUrl", req.getCallbackUrl(), true));
		fieldCheck.add(new MessageFieldCheck("notifyUrl", req.getNotifyUrl(), true));
		fieldCheck.add(new MessageFieldCheck("remark", req.getRemark(), true));

		// 非空、必填、固定值、长度
		String checkMsg = MessageFieldCheck.check(fieldCheck);
		if (StrKit.notBlank(checkMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), checkMsg);
		}
		if (FSRegex.isPositiveInt(req.getOrderPeriod()) == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "订单超时时间必须是正整数");
		}
		// 商户信息
		Merch merch = Merch.dao.selectFromRedis(req.getMerchCode());
		if (merch == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_MERCH);
		}
		// 是否禁用
		if (merch.getEnable() == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_MERCH_DISABLE);
		}

		// 交易策略
		TradeStrategy ts = TradeStrategy.dao.selectFromRedis(req.getMerchCode(), req.getPayType());
		if (ts == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_TRADE_STRA);
		}
		// 风控
		RiskRule rs = RiskRule.dao.selectFromRedis(ts.getRiskRuleId());
		RiskRuleCheck ruleCheck = new RiskRuleCheck(Integer.valueOf(req.getAmount()), req.getPayType(), req, rs);
		String riskRuleMsg = ruleCheck.check();
		if (StrKit.notBlank(riskRuleMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), riskRuleMsg);
		}

		// 商户号订单号是否存在
		if (TradeOrder.dao.orderExist(req.getMerchCode(), req.getMerchOrderNo())) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_ORDER_REPEAT);
		}
		// 交易要素
		TradeElement tradeElement = new TradeElement(req, merch, ts);
		return orderService.unionPay(req, tradeElement);
	}

	public BaseResp quickPaySet(QuickPaySetReq req) {
		BaseResp rsp = new BaseResp(req);
		if (FSRegex.isPositiveInt(req.getAmount()) == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "金额错误，金额以分为单位，必须是正整数");
		}
		List<MessageFieldCheck> fieldCheck = new ArrayList<MessageFieldCheck>();
		fieldCheck.add(new MessageFieldCheck("merchOrderNo", req.getMerchOrderNo(), true));
		fieldCheck.add(new MessageFieldCheck("amount", req.getAmount(), true));
		fieldCheck.add(new MessageFieldCheck("goodsName", req.getGoodsName(), true));
		fieldCheck.add(new MessageFieldCheck("orderPeriod", req.getOrderPeriod(), true));
		fieldCheck.add(new MessageFieldCheck("notifyUrl", req.getNotifyUrl(), true));
		// fieldCheck.add(new MessageFieldCheck("certNo", req.getCertNo(), true));
		// 签约ID有值时，不需要填写卡信息，否则必填
		if (StrKit.isBlank(req.getVerifyId())) {
			fieldCheck.add(new MessageFieldCheck("cardType", req.getCardType(), true));
			fieldCheck.add(new MessageFieldCheck("cardNo", req.getCardNo(), true));
			// fieldCheck.add(new MessageFieldCheck("bankType", req.getBankType(), true));
			fieldCheck.add(new MessageFieldCheck("certType", req.getCertType(), true));
			fieldCheck.add(new MessageFieldCheck("name", req.getName(), true));
			fieldCheck.add(new MessageFieldCheck("phone", req.getPhone(), true));

			if ("1".equals(req.getCardType())) {
				fieldCheck.add(new MessageFieldCheck("cvn2", req.getCvn2(), true));
				fieldCheck.add(new MessageFieldCheck("expired", req.getExpired(), true));
			}
		}

		// 非空、必填、固定值、长度
		String checkMsg = MessageFieldCheck.check(fieldCheck);
		if (StrKit.notBlank(checkMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), checkMsg);
		}
		if (FSRegex.isPositiveInt(req.getOrderPeriod()) == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "订单超时时间必须是正整数");
		}
		// 商户信息
		Merch merch = Merch.dao.selectFromRedis(req.getMerchCode());
		if (merch == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_MERCH);
		}
		// 是否禁用
		if (merch.getEnable() == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_MERCH_DISABLE);
		}

		// 交易策略
		TradeStrategy ts = null;
		if ("1".equals(req.getCardType())) {
			ts = TradeStrategy.dao.selectFromRedis(req.getMerchCode(), PayType.QUICK_PAY_CREDIT);
		} else {
			ts = TradeStrategy.dao.selectFromRedis(req.getMerchCode(), req.getPayType());
		}
		if (ts == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_TRADE_STRA);
		}
		// 风控
		RiskRule rs = RiskRule.dao.selectFromRedis(ts.getRiskRuleId());
		RiskRuleCheck ruleCheck = new RiskRuleCheck(Integer.valueOf(req.getAmount()), req.getPayType(), req, rs);
		String riskRuleMsg = ruleCheck.check();
		if (StrKit.notBlank(riskRuleMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), riskRuleMsg);
		}

		// 商户号订单号是否存在
		if (TradeOrder.dao.orderExist(req.getMerchCode(), req.getMerchOrderNo())) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_ORDER_REPEAT);
		}
		// 交易要素
		TradeElement tradeElement = new TradeElement(req, merch, ts);
		return orderService.quickPaySet(req, tradeElement);
	}

	public BaseResp quickPay(QuickPayReq req) {
		BaseResp rsp = new BaseResp(req);
		List<MessageFieldCheck> fieldCheck = new ArrayList<MessageFieldCheck>();
		fieldCheck.add(new MessageFieldCheck("token", req.getToken(), true));
		fieldCheck.add(new MessageFieldCheck("smsCode", req.getSmsCode(), true));
		fieldCheck.add(new MessageFieldCheck("orderNo", req.getOrderNo(), true));

		// 非空、必填、固定值、长度
		String checkMsg = MessageFieldCheck.check(fieldCheck);
		if (StrKit.notBlank(checkMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), checkMsg);
		}
		// 商户信息
		Merch merch = Merch.dao.selectFromRedis(req.getMerchCode());
		if (merch == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_MERCH);
		}
		// 是否禁用
		if (merch.getEnable() == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_MERCH_DISABLE);
		}
		return orderService.quickPay(req);
	}

	public BaseResp sendSMS(SendSMSReq req) {
		BaseResp rsp = new BaseResp(req);
		List<MessageFieldCheck> fieldCheck = new ArrayList<MessageFieldCheck>();
		fieldCheck.add(new MessageFieldCheck("orderNo", req.getOrderNo(), true));
		fieldCheck.add(new MessageFieldCheck("token", req.getToken(), true));

		// 非空、必填、固定值、长度
		String checkMsg = MessageFieldCheck.check(fieldCheck);
		if (StrKit.notBlank(checkMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), checkMsg);
		}
		// 商户信息
		Merch merch = Merch.dao.selectFromRedis(req.getMerchCode());
		if (merch == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_MERCH);
		}
		// 是否禁用
		if (merch.getEnable() == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_MERCH_DISABLE);
		}
		return orderService.sendSMS(req);
	}

	public BaseResp queryCardInfo(QueryCardInfoReq req) {
		BaseResp rsp = new BaseResp(req);
		List<MessageFieldCheck> fieldCheck = new ArrayList<MessageFieldCheck>();
		fieldCheck.add(new MessageFieldCheck("certNo", req.getCertNo(), true));

		// 非空、必填、固定值、长度
		String checkMsg = MessageFieldCheck.check(fieldCheck);
		if (StrKit.notBlank(checkMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), checkMsg);
		}
		// 商户信息
		Merch merch = Merch.dao.selectFromRedis(req.getMerchCode());
		if (merch == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_MERCH);
		}
		// 是否禁用
		if (merch.getEnable() == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_MERCH_DISABLE);
		}
		return orderService.queryCardInfo(req);
	}

	public BaseResp refund(RefundReq req) {
		BaseResp rsp = new BaseResp(req);
		List<MessageFieldCheck> fieldCheck = new ArrayList<MessageFieldCheck>();
		fieldCheck.add(new MessageFieldCheck("merchOrderNo", req.getMerchOrderNo(), true));
		fieldCheck.add(new MessageFieldCheck("refundOrderNo", req.getRefundOrderNo(), true));
		fieldCheck.add(new MessageFieldCheck("remark", req.getRemark(), true));

		// 非空、必填、固定值、长度
		String checkMsg = MessageFieldCheck.check(fieldCheck);
		if (StrKit.notBlank(checkMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), checkMsg);
		}
		// 商户信息
		Merch merch = Merch.dao.selectFromRedis(req.getMerchCode());
		if (merch == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_MERCH);
		}
		// 是否禁用
		if (merch.getEnable() == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_MERCH_DISABLE);
		}

		// 交易策略
		TradeStrategy ts = TradeStrategy.dao.selectFromRedis(req.getMerchCode(), req.getPayType());
		if (ts == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_TRADE_STRA);
		}
		// 商户号订单号是否存在
		if (TradeOrder.dao.orderExist(req.getMerchCode(), req.getMerchOrderNo())) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_ORDER_REPEAT);
		}
		// 退款订单是否存在
		TradeOrder orignOrder = TradeOrder.dao.selectByMerchOrderNo(req.getMerchCode(), req.getRefundOrderNo());
		if (orignOrder == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "退款订单不存在");
		}
		if (!orignOrder.getOrderStatus().equals(OrderStatus.Success.getValue())) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "该订单未交易成功,无法退款");
		}
		return orderService.refund(req, orignOrder);
	}

	public BaseResp df(DFReq req) {
		BaseResp rsp = new BaseResp(req);
		if (FSRegex.isPositiveInt(req.getAmount()) == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "金额错误，金额以分为单位，必须是正整数");
		}
		List<MessageFieldCheck> fieldCheck = new ArrayList<MessageFieldCheck>();
		fieldCheck.add(new MessageFieldCheck("merchOrderNo", req.getMerchOrderNo(), true));
		fieldCheck.add(new MessageFieldCheck("amount", req.getAmount(), true));
		fieldCheck.add(new MessageFieldCheck("accountName", req.getAccountName(), true));
		fieldCheck.add(new MessageFieldCheck("accountCardNo", req.getAccountCardNo(), true));
		fieldCheck.add(new MessageFieldCheck("notifyUrl", req.getNotifyUrl(), true));
		// 非空、必填、固定值、长度
		String checkMsg = MessageFieldCheck.check(fieldCheck);
		if (StrKit.notBlank(checkMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), checkMsg);
		}
		// 商户信息
		Merch merch = Merch.dao.selectFromRedis(req.getMerchCode());
		if (merch == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_MERCH);
		}
		// 是否禁用
		if (merch.getEnable() == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_MERCH_DISABLE);
		}
		// 交易策略
		TradeStrategy ts = TradeStrategy.dao.selectFromRedis(req.getMerchCode(), PayType.DF_PERSONAL);
		if (ts == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_TRADE_STRA);
		}
		// 风控
		RiskRule rs = RiskRule.dao.selectFromRedis(ts.getRiskRuleId());
		RiskRuleCheck ruleCheck = new RiskRuleCheck(Integer.valueOf(req.getAmount()), req.getPayType(), req, rs);
		String riskRuleMsg = ruleCheck.check();
		if (StrKit.notBlank(riskRuleMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), riskRuleMsg);
		}
		// 商户号订单号是否存在
		if (TradeOrder.dao.orderExist(req.getMerchCode(), req.getMerchOrderNo())) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_ORDER_REPEAT);
		}
		TradeElement tradeElement = new TradeElement(req, merch, ts);
		return orderService.df(req, tradeElement);
	}

	public BaseResp balanceQuery(QueryBalanceReq req) {
		QueryBalanceResp rsp = new QueryBalanceResp(req);
		Account account = Account.dao.selectByAccountNo(req.getMerchCode());
		if (account != null) {
			rsp.setCodeAndMsg(Resp.Success.getCode(), Resp.Success.getMsg());
			rsp.setBalance(account.getBalance().toString());
		} else {
			rsp.setCodeAndMsg(Resp.Fail.getCode(), Resp.Fail.getMsg());
		}
		rsp.setRespTime(FSDate.getDateTimeNumber());
		return rsp;
	}

	public BaseResp transferQrcode(TransferQrcodeReq req) {
		BaseResp rsp = new BaseResp(req);
		if (FSRegex.isPositiveInt(req.getAmount()) == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "金额错误，金额以分为单位，必须是正整数");
		}
		List<MessageFieldCheck> fieldCheck = new ArrayList<MessageFieldCheck>();
		fieldCheck.add(new MessageFieldCheck("merchOrderNo", req.getMerchOrderNo(), true));
		fieldCheck.add(new MessageFieldCheck("amount", req.getAmount(), true));
		fieldCheck.add(new MessageFieldCheck("notifyUrl", req.getNotifyUrl(), true));
		// 非空、必填、固定值、长度
		String checkMsg = MessageFieldCheck.check(fieldCheck);
		if (StrKit.notBlank(checkMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), checkMsg);
		}
		// 商户信息
		Merch merch = Merch.dao.selectFromRedis(req.getMerchCode());
		if (merch == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_MERCH);
		}
		// 是否禁用
		if (merch.getEnable() == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_MERCH_DISABLE);
		}
		// 交易策略
		TradeStrategy ts = TradeStrategy.dao.selectFromRedis(req.getMerchCode(), PayType.TRANSFER_QRCODE);
		if (ts == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_TRADE_STRA);
		}
		// 风控
		RiskRule rs = RiskRule.dao.selectFromRedis(ts.getRiskRuleId());
		RiskRuleCheck ruleCheck = new RiskRuleCheck(Integer.valueOf(req.getAmount()), req.getPayType(), req, rs);
		String riskRuleMsg = ruleCheck.check();
		if (StrKit.notBlank(riskRuleMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), riskRuleMsg);
		}
		// 商户号订单号是否存在
		if (TradeOrder.dao.orderExist(req.getMerchCode(), req.getMerchOrderNo())) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_ORDER_REPEAT);
		}
		TradeElement tradeElement = new TradeElement(req, merch, ts);
		return orderService.transferQrcode(req, tradeElement);
	}

	public BaseResp bindBankCard(BindBankCardReq req) {
		BaseResp rsp = new BaseResp(req);
		List<MessageFieldCheck> fieldCheck = new ArrayList<MessageFieldCheck>();
		fieldCheck.add(new MessageFieldCheck("merchOrderNo", req.getMerchOrderNo(), true));
		fieldCheck.add(new MessageFieldCheck("certType", req.getCertType(), true));
		fieldCheck.add(new MessageFieldCheck("certNo", req.getCertNo(), true));
		fieldCheck.add(new MessageFieldCheck("cardType", req.getCardType(), true));
		fieldCheck.add(new MessageFieldCheck("cardNo", req.getCardNo(), true));
		fieldCheck.add(new MessageFieldCheck("name", req.getName(), true));
		fieldCheck.add(new MessageFieldCheck("phone", req.getPhone(), true));
		if ("1".equals(req.getCardType())) {
			fieldCheck.add(new MessageFieldCheck("cvn2", req.getCvn2(), true));
			fieldCheck.add(new MessageFieldCheck("expired", req.getExpired(), true));
		}
		// 非空、必填、固定值、长度
		String checkMsg = MessageFieldCheck.check(fieldCheck);
		if (StrKit.notBlank(checkMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), checkMsg);
		}
		// 商户信息
		Merch merch = Merch.dao.selectFromRedis(req.getMerchCode());
		if (merch == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_MERCH);
		}
		// 是否禁用
		if (merch.getEnable() == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_MERCH_DISABLE);
		}
		// 交易策略
		TradeStrategy ts = TradeStrategy.dao.selectFromRedis(req.getMerchCode(), req.getPayType());
		if (ts == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_TRADE_STRA);
		}
		// 商户号订单号是否存在
		if (TradeOrder.dao.orderExist(req.getMerchCode(), req.getMerchOrderNo())) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_ORDER_REPEAT);
		}
		// 交易要素
		TradeElement tradeElement = new TradeElement(req, merch, ts);
		return orderService.bindBankCard(req, tradeElement);
	}

	public BaseResp bindBankCardVerify(BindBankCardVerifyReq req) {
		BaseResp rsp = new BaseResp(req);
		List<MessageFieldCheck> fieldCheck = new ArrayList<MessageFieldCheck>();
		fieldCheck.add(new MessageFieldCheck("merchOrderNo", req.getMerchOrderNo(), true));
		fieldCheck.add(new MessageFieldCheck("cardNo", req.getCardNo(), true));
		fieldCheck.add(new MessageFieldCheck("phone", req.getPhone(), true));
		fieldCheck.add(new MessageFieldCheck("orderNo", req.getOrderNo(), true));
		fieldCheck.add(new MessageFieldCheck("smsCode", req.getSmsCode(), true));
		// 非空、必填、固定值、长度
		String checkMsg = MessageFieldCheck.check(fieldCheck);
		if (StrKit.notBlank(checkMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), checkMsg);
		}
		// 商户信息
		Merch merch = Merch.dao.selectFromRedis(req.getMerchCode());
		if (merch == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_MERCH);
		}
		// 是否禁用
		if (merch.getEnable() == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_MERCH_DISABLE);
		}
		// 交易策略
		TradeStrategy ts = TradeStrategy.dao.selectFromRedis(req.getMerchCode(), req.getPayType());
		if (ts == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_TRADE_STRA);
		}
		// 商户号订单号是否存在
		if (TradeOrder.dao.orderExist(req.getMerchCode(), req.getMerchOrderNo())) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_ORDER_REPEAT);
		}
		// 交易要素
		TradeElement tradeElement = new TradeElement(req, merch, ts);
		return orderService.bindBankCardVerify(req, tradeElement);
	}
	
	public BaseResp blankNote(BlankNoteReq blankNoteReq) {
		BaseResp rsp = new BaseResp(blankNoteReq);
//		if (FSRegex.isPositiveInt(req.getAmount()) == false) {
//			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "金额错误，金额以分为单位，必须是正整数");
//		}
		return null;
		
	}

	public BaseResp appidPay(AppidPayReq req) {
		BaseResp rsp = new BaseResp(req);
		if (FSRegex.isPositiveInt(req.getAmount()) == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "金额错误，金额以分为单位，必须是正整数");
		}

		Integer amount = Integer.parseInt(req.getAmount());
		// TODO 限制交易金额大于99元
		if ("000088880000299".equals(req.getMerchCode()) && amount <= 9900) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "交易金额须大于99元");
		}
		List<MessageFieldCheck> fieldCheck = new ArrayList<MessageFieldCheck>();
		fieldCheck.add(new MessageFieldCheck("merchOrderNo", req.getMerchOrderNo(), true));
		fieldCheck.add(new MessageFieldCheck("amount", req.getAmount(), true));
		fieldCheck.add(new MessageFieldCheck("notifyUrl", req.getNotifyUrl(), true));
		// 非空、必填、固定值、长度
		String checkMsg = MessageFieldCheck.check(fieldCheck);
		if (StrKit.notBlank(checkMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), checkMsg);
		}
		// 商户信息
		Merch merch = Merch.dao.selectFromRedis(req.getMerchCode());
		if (merch == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_MERCH);
		}
		// 是否禁用
		if (merch.getEnable() == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_MERCH_DISABLE);
		}

		TradeStrategy ts = null;
		if (PayType.ALIPAY_PUBLIC.equals(req.getPayType())) {
			// 交易策略
			ts = TradeStrategy.dao.selectFromRedis(req.getMerchCode(), PayType.ALIPAY_PUBLIC);
		}
		if (PayType.ALIPAY_QRCODE.equals(req.getPayType())) {
			// 交易策略
			ts = TradeStrategy.dao.selectFromRedis(req.getMerchCode(), PayType.ALIPAY_QRCODE);
		}
		if (PayType.WECHAT_PUBLIC.equals(req.getPayType())) {
			// 交易策略
			ts = TradeStrategy.dao.selectFromRedis(req.getMerchCode(), PayType.WECHAT_PUBLIC);
		}
		if (PayType.WECHAT_QRCODE.equals(req.getPayType())) {
			// 交易策略
			ts = TradeStrategy.dao.selectFromRedis(req.getMerchCode(), PayType.WECHAT_QRCODE);
		}

		if (ts == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_TRADE_STRA);
		}

		// 风控
		RiskRule rs = RiskRule.dao.selectFromRedis(ts.getRiskRuleId());
		RiskRuleCheck ruleCheck = new RiskRuleCheck(Integer.valueOf(req.getAmount()), req.getPayType(), req, rs);
		String riskRuleMsg = ruleCheck.check();
		if (StrKit.notBlank(riskRuleMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), riskRuleMsg);
		}
		// 商户号订单号是否存在
		if (TradeOrder.dao.orderExist(req.getMerchCode(), req.getMerchOrderNo())) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_ORDER_REPEAT);
		}
		TradeElement tradeElement = new TradeElement(req, merch, ts);
		return orderService.appidPay(req, tradeElement);
	}

	public BaseResp wxgjRefund(RefundReq req) {
		BaseResp rsp = new BaseResp(req);

		List<MessageFieldCheck> fieldCheck = new ArrayList<MessageFieldCheck>();
		fieldCheck.add(new MessageFieldCheck("merchOrderNo", req.getMerchOrderNo(), true));
		fieldCheck.add(new MessageFieldCheck("refundOrderNo", req.getRefundOrderNo(), true));
		fieldCheck.add(new MessageFieldCheck("amount", req.getAmount(), true));
		fieldCheck.add(new MessageFieldCheck("remark", req.getRemark(), true));

		String checkMsg = MessageFieldCheck.check(fieldCheck);
		if (StrKit.notBlank(checkMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), checkMsg);
		}

		// 商户信息
		Merch merch = Merch.dao.selectFromRedis(req.getMerchCode());
		if (merch == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_MERCH);
		}

		TradeStrategy ts = null;
		// 交易策略
		ts = TradeStrategy.dao.selectFromRedis(req.getMerchCode(), req.getPayType());
		if (ts == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_TRADE_STRA);
		}

		// 退款订单是否存在
		TradeOrder orignOrder = TradeOrder.dao.selectByMerchOrderNo(req.getMerchCode(), req.getRefundOrderNo());
		if (orignOrder == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "退款订单不存在");
		}
		if (!orignOrder.getOrderStatus().equals(OrderStatus.Success.getValue())) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "该订单未交易成功,无法退款");
		}
		return orderService.wxgjRefund(req, orignOrder, ts);

	}

	public BaseResp wxgjGetClearingData(WxgjClearingReq req) {
		BaseResp rsp = new BaseResp(req);
		List<MessageFieldCheck> fieldCheck = new ArrayList<MessageFieldCheck>();
		fieldCheck.add(new MessageFieldCheck("date_start", req.getDate_start(), true));
		fieldCheck.add(new MessageFieldCheck("date_end", req.getDate_end(), true));
		String checkMsg = MessageFieldCheck.check(fieldCheck);
		if (StrKit.notBlank(checkMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), checkMsg);
		}
		// 商户信息
		Merch merch = Merch.dao.selectFromRedis(req.getMerchCode());
		if (merch == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_MERCH);
		}
		
		TradeStrategy ts = TradeStrategy.dao.selectFromRedis(req.getMerchCode(), PayType.WXGJPAY_PUBLIC);
		if(ts == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_TRADE_STRA);
		}
		
		return orderService.wxgjGetClearingData(req, ts);
	}

	public BaseResp wxgjRefundQuery(RefundReq req) {
		BaseResp rsp = new BaseResp(req);
		List<MessageFieldCheck> fieldCheck = new ArrayList<MessageFieldCheck>();
		fieldCheck.add(new MessageFieldCheck("refundOrderNo", req.getRefundOrderNo(), true));
		String checkMsg = MessageFieldCheck.check(fieldCheck);
		if (StrKit.notBlank(checkMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), checkMsg);
		}

		// 商户信息
		Merch merch = Merch.dao.selectFromRedis(req.getMerchCode());
		if (merch == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_MERCH);
		}
		// 退款订单是否存在
		TradeOrder orignOrder = TradeOrder.dao.selectByMerchOrderNo(req.getMerchCode(), req.getRefundOrderNo());
		if (orignOrder == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "退款订单不存在");
		}
		if (!orignOrder.getOrderStatus().equals(OrderStatus.Success.getValue())) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "该订单未交易成功,无法退款");
		}
		return orderService.wxgjRefundQuery(req, orignOrder);

	}
	
	public BaseResp wxgjappidPay(AppidWxgjPayReq req) {
		BaseResp rsp = new BaseResp(req);
		if (FSRegex.isPositiveInt(req.getAmount()) == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), "金额错误，金额以分为单位，必须是正整数");
		}
		// Integer amount = Integer.parseInt(req.getAmount());

		// TODO 临时增加金额限制为最低100元
		/*
		 * if (amount < 10000) { return rsp.setCodeAndMsg(Resp.Fail.getCode(),
		 * "最低金额限制为100元"); }
		 */
		List<MessageFieldCheck> fieldCheck = new ArrayList<MessageFieldCheck>();
		fieldCheck.add(new MessageFieldCheck("merchOrderNo", req.getMerchOrderNo(), true));
		fieldCheck.add(new MessageFieldCheck("amount", req.getAmount(), true));
		fieldCheck.add(new MessageFieldCheck("notifyUrl", req.getNotifyUrl(), true));
		// 非空、必填、固定值、长度
		String checkMsg = MessageFieldCheck.check(fieldCheck);
		if (StrKit.notBlank(checkMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), checkMsg);
		}
		// 商户信息
		Merch merch = Merch.dao.selectFromRedis(req.getMerchCode());
		if (merch == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_MERCH);
		}
		// 微信跨境支付是否配置了商户的交易币种
		if (null == merch.getCointype() || "".equals(merch.getCointype()) || 3 != merch.getCointype().length()) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_ERROR_MERCH_COINTYPE);
		}

		// 是否禁用
		if (merch.getEnable() == false) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_MERCH_DISABLE);
		}

		TradeStrategy ts = null;

		if (PayType.WXGJPAY_PUBLIC.equals(req.getPayType()) || PayType.WXGJPAY_MICORPAY.equals(req.getPayType())
				|| PayType.WXGJPAY_QRCODE.equals(req.getPayType())) {
			if (PayType.WXGJPAY_MICORPAY.equals(req.getPayType())) {
				if (null == req.getAuth_code() || req.getAuth_code().length() == 0) {
					return rsp.setCodeAndMsg(Resp.Fail.getCode(), "授权码信息错误");
				}
			}
			// 交易策略
			ts = TradeStrategy.dao.selectFromRedis(req.getMerchCode(), req.getPayType());
		}

		if (ts == null) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_NO_TRADE_STRA);
		}

		// 风控
		RiskRule rs = RiskRule.dao.selectFromRedis(ts.getRiskRuleId());
		RiskRuleCheck ruleCheck = new RiskRuleCheck(Integer.valueOf(req.getAmount()), req.getPayType(), req, rs);
		String riskRuleMsg = ruleCheck.check();
		if (StrKit.notBlank(riskRuleMsg)) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), riskRuleMsg);
		}
		// 商户号订单号是否存在
		if (TradeOrder.dao.orderExist(req.getMerchCode(), req.getMerchOrderNo())) {
			return rsp.setCodeAndMsg(Resp.Fail.getCode(), R.MSG_ORDER_REPEAT);
		}
		TradeElement tradeElement = new TradeElement(req, merch, ts);
		return orderService.wxgjappidPay(req, tradeElement);
	}

}
